package com.ruoyi.system.utils;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import com.ruoyi.common.utils.uuid.UUID;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;

@Component
public  class SysTencentCOSUtil {

    @Value("${tencent.cos.secretId}")
    private String secretId;

    @Value("${tencent.cos.secretKey}")
    private String secretKey;

    @Value("${tencent.cos.bucketName}")
    private String bucketName;

    @Value("${tencent.cos.region}")
    private String region;

    // 初始化客户端
    private COSClient getCosClient() {
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        Region region = new Region(this.region);
        ClientConfig clientConfig = new ClientConfig(region);
        clientConfig.setHttpProtocol(HttpProtocol.https);
        return new COSClient(cred, clientConfig);
    }


    //获取文件key
    private static String fileKey(MultipartFile file){
        // 避免文件覆盖，获取文件的原始名称，如123.jpg,然后通过截取获得文件的后缀，也就是文件的类型
        String originalFilename = file.getOriginalFilename();
        //获取文件的类型
        String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
        //使用UUID工具  创建唯一名称，放置文件重名被覆盖，在拼接上上命令获取的文件类型
        String fileName = UUID.randomUUID().toString() + fileType;
        // 指定文件上传到 COS 上的路径，即对象键。最终文件会传到存储桶名字中的images文件夹下的fileName名字
        String key = "images/" + fileName;
        return key;
    }

    // 分块上传
    private String uploadPartDemo( MultipartFile  file) {
        String key=fileKey(file);
        System.out.println("key:"+key);

        //分片上次初始化
        InitiateMultipartUploadRequest initRequest =
                new InitiateMultipartUploadRequest(bucketName, key);
        InitiateMultipartUploadResult initResponse =
                getCosClient().initiateMultipartUpload(initRequest);
        String uploadId = initResponse.getUploadId();

        //获取对象建
        boolean userTrafficLimit = false;
        List<PartETag> partETags = new LinkedList<>();
        try (InputStream inputStream = file.getInputStream()) {
            byte[] data = IOUtils.toByteArray(inputStream);
            int partSize = 1024 * 1024 * 20; // 每个分片大小为20MB
            int partCount = (int) Math.ceil((double) data.length / partSize);

            for (int i = 0; i < partCount; i++) {
                int start = i * partSize;
                int end = Math.min(start + partSize, data.length);
                byte[] partData = new byte[end - start];
                System.arraycopy(data, start, partData, 0, partData.length);

                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(key);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setInputStream(new ByteArrayInputStream(partData));
                uploadPartRequest.setPartSize(partData.length);
                uploadPartRequest.setPartNumber(i + 1);

                if (userTrafficLimit) {
                    uploadPartRequest.setTrafficLimit(8 * 1024 * 1024); // 限速8MB/s
                }

                UploadPartResult putResult = getCosClient().uploadPart(uploadPartRequest);
                PartETag partETag = putResult.getPartETag();
                partETags.add(partETag);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("分块上传失败: " + e.getMessage(), e);
        }
        CompleteMultipartUploadRequest compRequest =
                new CompleteMultipartUploadRequest(bucketName, key, uploadId, partETags);
        try {
            CompleteMultipartUploadResult compResult =
                    getCosClient().completeMultipartUpload(compRequest);
            System.out.println("文件上传完成: " + compResult.getLocation());
            //关闭客户端
            getCosClient().shutdown();
            return compResult.getLocation();

        } catch (CosServiceException e) {
            System.err.println("完成分片上传失败: " + e.getErrorMessage());
            return null;
        }
    }


    // 上传文件返回文件路径
    public String upLoadFile(MultipartFile file) {
        String url=uploadPartDemo(file);
        return url;
    }

    // 构建文件访问路径
    private String buildFileUrl(String key) {
        return String.format("https://%s.cos.%s.myqcloud.com/%s", bucketName, region, key);
    }

    // 删除服务器指定文件
    public void deleteFile(String bucketName,String key) {
        getCosClient().deleteObject(bucketName, key);
    }
}